package com.zhouyer.study.service.impl;

import com.zhouyer.study.dao.UserDao;
import com.zhouyer.study.dto.UserDTO;
import com.zhouyer.study.entity.ZhouyerUser;
import com.zhouyer.study.service.UserService;
import com.zhouyer.study.service.feign.CodeFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
import java.util.UUID;

/**
 * 用户相关服务实现
 *
 * @author zhouyao
 * @version 1.0
 * @date 2021/12/7 11:51 上午
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Resource
    private CodeFeignClient codeFeignClient;

    @Override
    public Integer register(HttpServletResponse response, UserDTO userDTO) {
        String email = userDTO.getEmail();
        String code = userDTO.getCode();
        String pwd = userDTO.getPassword();
        // 0:注册成功，-1：注册失败，1：用户已注册，2：验证码错误，3：验证码超时
        // 如果通过email查询有记录，说明已经注册过
        if (isRegistered(email)) {
            return 1;
        }
        // 校验验证码是否正确，0正确1错误2超时
        Integer codeValidateRes = codeFeignClient.validateCode(email, code);
        if (codeValidateRes == 1) {
            // 验证码不正确
            return 2;
        }
        if (codeValidateRes == 2) {
            // 验证码超时
            return 3;
        }
        // 根据email和pwd生成token，并存入数据库
        String token = saveToken(ZhouyerUser.builder().email(email).password(pwd).build());
        // 将token写入cookie中，返回给客户端
        addCookie(response, "token", token);
        return 0;
    }

    @Override
    public Boolean isRegistered(String email) {
        ZhouyerUser zhouyerUser = userDao.findByEmail(email);
        if (null != zhouyerUser) {
            return true;
        }
        return false;
    }

    @Override
    public String login(HttpServletResponse response, String email, String pwd) {
        ZhouyerUser zhouyerUser = userDao.findByEmail(email);
        if (null == zhouyerUser || !StringUtils.equals(zhouyerUser.getPassword(), pwd)) {
            // 用户名或密码错误
            return StringUtils.EMPTY;
        }
        // 根据email和pwd生成token，并存入数据库
        String token = saveToken(zhouyerUser);
        // 将token写入cookie中，返回给客户端
        addCookie(response, "token", token);
        return zhouyerUser.getEmail();
    }

    @Override
    public String findEmailByToken(String token) {
        ZhouyerUser zhouyerUser = userDao.findByToken(token);
        return Optional.ofNullable(zhouyerUser).map(ZhouyerUser::getEmail).orElse(null);
    }

    private void addCookie(HttpServletResponse response, String key, String val) {
        // 创建一个cookie对象，并将token保存到cookie对象中
        Cookie cookie = new Cookie(key, val);
        // 设置cookie的过期时间，单位为秒，这里是5分钟
        cookie.setMaxAge(300);
        cookie.setPath("/");
        // 通过response的addCookie()方法将此Cookie对象保存到客户端浏览器的cookie中
        response.addCookie(cookie);
    }

    private String saveToken(ZhouyerUser zhouyerUser) {
        // 根据email和pwd生成token，并存入数据库
        // uuid模拟token
        String token = UUID.randomUUID().toString();
        try {
            zhouyerUser.setToken(token);
            // 保存到数据库，密码这里演示就用明文，在实际开发中一定要通过加密算法进行加密，如md5
            userDao.save(zhouyerUser);
        } catch (Exception e) {
            log.error("保存token失败", e);
            return StringUtils.EMPTY;
        }
        return token;
    }
}
